<template>
  <div class="dashboard-container">
    <div class="dashboard-overview">
      <ul class="overview-tags">
        <li class="overview-tags-item">
          <div class="overview-tags-item-title">总用户数</div>
          <div class="overview-tags-item-content"><span class="item-content-num">{{ totalUsers }}</span><span class="item-content-unit">人</span></div>
        </li>
        <li class="overview-tags-item">
          <div class="overview-tags-item-title">总任务数</div>
          <div class="overview-tags-item-content"><span class="item-content-num">{{ totalJobs }}</span><span class="item-content-unit">个</span></div>
        </li>
        <li class="overview-tags-item">
          <div class="overview-tags-item-title">总数据集数</div>
          <div class="overview-tags-item-content"><span class="item-content-num">{{ totalDatasets }}</span><span class="item-content-unit">个</span></div>
        </li>
        <li class="overview-tags-item">
          <div class="overview-tags-item-title">总公开项目数</div>
          <div class="overview-tags-item-content"><span class="item-content-num">{{ totalPublicProjects }}</span><span class="item-content-unit">个</span></div>
        </li>
        <li class="overview-tags-item">
          <div class="overview-tags-item-title">机器数</div>
          <div class="overview-tags-item-content"><span class="item-content-num">{{ totalNodes }}</span><span class="item-content-unit">台</span></div>
        </li>
        <li class="overview-tags-item">
          <div class="overview-tags-item-title">GPU卡数</div>
          <div class="overview-tags-item-content"><span class="item-content-num">{{ totalGpus }}</span><span class="item-content-unit">块</span></div>
        </li>
        <li class="overview-tags-item">
          <div class="overview-tags-item-title">当前告警数</div>
          <div class="overview-tags-item-content"><span class="item-content-num">{{ totalAlerts }}</span><span class="item-content-unit">个</span><i class="view-alarm el-icon-view" @click="toViewALarm" /></div>
        </li>
      </ul>
    </div>
    <div class="dashboard-body">
      <ul class="dashboard-body-tabs">
        <li :class="{'dashboard-body-tabs-active-tab': activeTab === 0 }" class="dashboard-body-tabs-item" @click="toggleActiveTab(0)">用户数据</li>
        <li :class="{'dashboard-body-tabs-active-tab': activeTab === 1 }" class="dashboard-body-tabs-item" @click="toggleActiveTab(1)">任务统计</li>
        <li :class="{'dashboard-body-tabs-active-tab': activeTab === 2 }" class="dashboard-body-tabs-item" @click="toggleActiveTab(2)">资源统计</li>
      </ul>
      <div class="dashboard-body-content">
        <div v-if="activeTab === 0">
          <div>
            <div class="chart-header">
              <span>活跃用户数</span>
              <el-select
                v-model="selectedUserPeriod"
                size="mini"
                placeholder="请选择"
                @change="handleUserPeriodSelect">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value" />
              </el-select>
            </div>
            <div id="myUserChart" style="width: 100%; height: 292px"/>
          </div>
          <div class="users-info">
            <div class="users-info-left">
              <div class="users-info-header">
                <span>任务数量排行TOP10的用户</span>
              </div>
              <div class="users-info-top-user">
                <ul class="users-info-top-user-list">
                  <li v-for="(item, i) in topUsers" :key="i" class="users-info-top-user-item">
                    <p class="top-user-item-name">{{ item.username }}</p>
                    <p class="top-user-item-value">任务数量：{{ item.value }}</p>
                  </li>
                </ul>
              </div>
            </div>
            <div class="users-info-right">
              <div class="users-info-header">
                <span>用户任务时长排行榜</span>
                <el-select
                  v-model="selectedTaskTimePeriod"
                  size="mini"
                  placeholder="请选择"
                  @change="handleUserTaskTimeSelect">
                  <el-option
                    v-for="item in options"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value" />
                </el-select>
              </div>
              <div class="users-info-task-time">
                <div id="myTaskTimeChart" style="width: 100%; height: 400px"/>
              </div>
            </div>
          </div>
        </div>
        <div v-if="activeTab === 1">
          <div class="task-analysis-header">
            <span :class="{'task-analysis-header-active-tab': activeTaskAnalysisTab === 0 }" class="task-analysis-item" @click="toggleTaskAnalysisActiveTab(0)">新建任务数</span>
            <span :class="{'task-analysis-header-active-tab': activeTaskAnalysisTab === 1 }" class="task-analysis-item" @click="toggleTaskAnalysisActiveTab(1)">任务分析</span>
          </div>
          <div v-if="activeTaskAnalysisTab === 0">
            <div class="chart-header">
              <span>新建任务数</span>
              <el-select
                v-model="selectedNewTaskPeriod"
                size="mini"
                placeholder="请选择"
                @change="handleNewTaskPeriodSelect">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value" />
              </el-select>
            </div>
            <div id="myNewTaskChart" style="width: 100%; height: 292px"/>
          </div>
          <div v-if="activeTaskAnalysisTab === 1">
            <div class="chart-header">
              <span>任务分析</span>
              <el-select
                v-model="selectedTaskStatusPeriod"
                size="mini"
                placeholder="请选择"
                @change="handleTaskStatusPeriodSelect">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value" />
              </el-select>
            </div>
            <div id="myTaskStatusChart" style="width: 100%; height: 292px; margin-bottom: 40px;"/>
          </div>
          <div class="task-time-box">
            <div class="task-time-table-header">
              <span>耗时任务排行榜</span>
              <el-select
                v-model="selectedTaskTimeRankPeriod"
                size="mini"
                placeholder="请选择"
                @change="handleTaskTimePeriodSelect">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value" />
              </el-select>
            </div>
            <el-table
              :data="taskTimeList"
              :header-row-class-name="handleTableHeaderclass"
              style="width: 100%"
              class="task-time-table">
              <el-table-column align="center" label="任务名称">
                <template slot-scope="scope">
                  {{ scope.row.name }}
                </template>
              </el-table-column>
              <el-table-column align="center" label="所用时长">
                <template slot-scope="scope">
                  {{ scope.row.value }}
                </template>
              </el-table-column>
              <el-table-column align="center" label="用户名称">
                <template slot-scope="scope">
                  {{ scope.row.username }}
                </template>
              </el-table-column>
              <el-table-column align="center" label="创建时间" width="300">
                <template slot-scope="scope">
                  <span>{{ scope.row.begintime ? new Date(Date.parse(new Date(scope.row.begintime))).Format("yyyy-MM-dd hh:mm:ss") : '-' }}</span>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </div>
        <div v-if="activeTab === 2">
          <div class="task-analysis-header">
            <span :class="{'task-analysis-header-active-tab': activeResourceTab === 0 }" class="task-analysis-item" @click="toggleResourceActiveTab(0)">GPU分析</span>
            <span :class="{'task-analysis-header-active-tab': activeResourceTab === 1 }" class="task-analysis-item" @click="toggleResourceActiveTab(1)">CPU利用率</span>
            <span :class="{'task-analysis-header-active-tab': activeResourceTab === 2 }" class="task-analysis-item" @click="toggleResourceActiveTab(2)">内存利用率</span>
          </div>
          <div
            v-loading="listLoading"
            v-if="activeResourceTab === 0"
            element-loading-text="图表加载中，请稍候"
            element-loading-spinner="el-icon-loading"
            element-loading-background="#ffffff"
          >
            <div class="chart-header">
              <span>GPU分析</span>
              <el-select
                v-model="selectedResourceGPUPeriod"
                size="mini"
                placeholder="请选择"
                @change="handleResourceGPUPeriodSelect">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value" />
              </el-select>
            </div>
            <div id="myResourceGPUChart" style="width: 100%; height: 400px; margin-bottom: 80px;"/>
          </div>
          <div
            v-loading="listLoading"
            v-if="activeResourceTab === 1"
            element-loading-text="图表加载中，请稍候"
            element-loading-spinner="el-icon-loading"
            element-loading-background="#ffffff"
          >
            <div class="chart-header">
              <span>CPU利用率</span>
              <el-select
                v-model="selectedResourceCPUPeriod"
                size="mini"
                placeholder="请选择"
                @change="handleResourceCPUPeriodSelect">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value" />
              </el-select>
            </div>
            <div id="myResourceCPUChart" style="width: 100%; height: 400px; margin-bottom: 80px;"/>
          </div>
          <div
            v-loading="listLoading"
            v-if="activeResourceTab === 2"
            element-loading-text="图表加载中，请稍候"
            element-loading-spinner="el-icon-loading"
            element-loading-background="#ffffff"
          >
            <div class="chart-header">
              <span>内存利用率</span>
              <el-select
                v-model="selectedResourceMemPeriod"
                size="mini"
                placeholder="请选择"
                @change="handleResourceMemPeriodSelect">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value" />
              </el-select>
            </div>
            <div id="myResourceMemChart" style="width: 100%; height: 400px; margin-bottom: 80px;"/>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {
  getDashboardOverview,
  getDashboardUsersView,
  getDashboardTopUsers,
  getDashboardTopUsersHours,
  getDashboardJobsView,
  getDashboardTopJobsHoursView,
  getDashboardJobsStatusView,
  getDashboardResourceGpuUtilView,
  getDashboardResourceGpuAllocateView,
  getDashboardResourceCpuView,
  getDashboardResourceMemoryView
} from '@/api/dashboard'
import { initChart, drawLine, drawBar, drawTaskLine, drawResourceGPULine } from '@/utils/echarts'

export default {
  name: 'Dashboard',
  data() {
    return {
      // 概览
      listLoading: true,
      totalAlerts: 0,
      totalDatasets: 0,
      totalGpus: 0,
      totalJobs: 0,
      totalNodes: 0,
      totalPublicProjects: 0,
      totalUsers: 0,
      // body
      activeTab: 0,
      activeTaskAnalysisTab: 0,
      activeResourceTab: 0,
      options: [
        {
          value: 7,
          label: '最近7天'
        },
        {
          value: 30,
          label: '最近30天'
        }
      ],
      // 选择时间周期
      selectedUserPeriod: 7,
      // 选择用户任务时长周期
      selectedTaskTimePeriod: 7,
      // 选择用户任务时长周期
      selectedNewTaskPeriod: 7,
      // 选择任务耗时排行周期
      selectedTaskTimeRankPeriod: 7,
      // 选择任务分析周期
      selectedTaskStatusPeriod: 7,
      // 选择资源GPU周期
      selectedResourceGPUPeriod: 7,
      // 选择资源GPU周期
      selectedResourceCPUPeriod: 7,
      // 选择资源GPU周期
      selectedResourceMemPeriod: 7,
      // 活跃用户数图表
      myUserChart: '',
      // 用户任务时长排行图表
      myTaskTimeChart: '',
      // 新增任务数图表
      myNewTaskChart: '',
      // 任务分析图表
      myTaskStatusChart: '',
      // 资源使用率图表-GPU
      myResourceGPUChart: '',
      // 资源使用率图表-CPU
      myResourceCPUChart: '',
      // 资源使用率图表-GPU
      myResourceMemChart: '',
      // 任务数量排行TOP10用户
      topUsers: [],
      // 耗时任务排行榜
      taskTimeList: []
    }
  },
  created() {
    this._getDashboardOverview()
    this._getDashboardUsersView(this.selectedUserPeriod)
    this._getDashboardTopUsers()
    this._getDashboardTopUsersHours(this.selectedTaskTimePeriod)
    this.$nextTick(function() {
      window.addEventListener('resize', this.resize)
    })
  },
  methods: {
    // 切换激活页签
    toggleActiveTab(val) {
      this.activeTab = val
      this.clearChart()
      switch (val) {
        case 0:
          this._getDashboardUsersView(this.selectedUserPeriod)
          this._getDashboardTopUsersHours(this.selectedTaskTimePeriod)
          break
        case 1:
          this.activeTaskAnalysisTab = 0
          this._getDashboardJobsView(this.selectedNewTaskPeriod)
          this._getDashboardTopJobsHoursView(this.selectedTaskTimeRankPeriod)
          break
        case 2:
          this.activeResourceTab = 0
          this._getDashboardResourceGPU(this.selectedResourceGPUPeriod)
          break
      }
    },
    // 切换任务统计Tab
    toggleTaskAnalysisActiveTab(val) {
      this.activeTaskAnalysisTab = val
      this.clearChart()
      switch (val) {
        case 0:
          this._getDashboardJobsView(this.selectedNewTaskPeriod)
          break
        case 1:
          this._getDashboardJobsStatusView(this.selectedTaskStatusPeriod)
          break
      }
    },
    // 切换资源统计Tab
    toggleResourceActiveTab(val) {
      this.activeResourceTab = val
      this.clearChart()
      switch (val) {
        case 0:
          this._getDashboardResourceGPU(this.selectedResourceGPUPeriod)
          break
        case 1:
          this._getDashboardResourceCPU(this.selectedResourceCPUPeriod)
          break
        case 2:
          this._getDashboardResourceMem(this.selectedResourceMemPeriod)
          break
      }
    },
    // 清理图表实例
    clearChart() {
      if (this.myUserChart) {
        this.myUserChart.clear()
      }
      if (this.myTaskTimeChart) {
        this.myTaskTimeChart.clear()
      }
      if (this.myTaskStatusChart) {
        this.myTaskStatusChart.clear()
      }
      if (this.myNewTaskChart) {
        this.myNewTaskChart.clear()
      }
      if (this.myResourceGPUChart) {
        this.myResourceGPUChart.clear()
      }
    },
    // 活跃用户选择时间段
    handleUserPeriodSelect(val) {
      this._getDashboardUsersView(val)
    },
    // 用户任务时长排行版
    handleUserTaskTimeSelect(val) {
      this._getDashboardTopUsersHours(val)
    },
    // 新建任务数选择时间段
    handleNewTaskPeriodSelect(val) {
      this._getDashboardJobsView(val)
    },
    // 耗时任务排行榜选择时间段
    handleTaskTimePeriodSelect(val) {
      this._getDashboardTopJobsHoursView(val)
    },
    // 任务分析选择时间段
    handleTaskStatusPeriodSelect(val) {
      this._getDashboardJobsStatusView(val)
    },
    // 资源GPU选择时间段
    handleResourceGPUPeriodSelect(val) {
      this._getDashboardResourceGPU(val)
    },
    // 资源CPU选择时间段
    handleResourceCPUPeriodSelect(val) {
      this._getDashboardResourceCPU(val)
    },
    // 资源内存选择时间段
    handleResourceMemPeriodSelect(val) {
      this._getDashboardResourceMem(val)
    },
    // 绘制图表
    drawChart(chartName, xData, yData1, yData2) {
      let insChart = initChart(chartName)
      switch (chartName) {
        case 'myUserChart':
          this.myUserChart = insChart
          insChart = drawLine(this.myUserChart, xData, yData1)
          this.myUserChart.resize()
          break
        case 'myTaskTimeChart':
          this.myTaskTimeChart = insChart
          insChart = drawBar(this.myTaskTimeChart, xData, yData1)
          this.myTaskTimeChart.resize()
          break
        case 'myNewTaskChart':
          this.myNewTaskChart = insChart
          insChart = drawLine(this.myNewTaskChart, xData, yData1)
          this.myNewTaskChart.resize()
          break
        case 'myTaskStatusChart':
          this.myTaskStatusChart = insChart
          insChart = drawTaskLine(this.myTaskStatusChart, xData, yData1, yData2)
          this.myTaskStatusChart.resize()
          break
        case 'myResourceGPUChart':
          this.myResourceGPUChart = insChart
          insChart = drawResourceGPULine(this.myResourceGPUChart, xData, yData1, yData2)
          this.myResourceGPUChart.resize()
          break
        case 'myResourceCPUChart':
          this.myResourceCPUChart = insChart
          insChart = drawLine(this.myResourceCPUChart, xData, yData1)
          this.myResourceCPUChart.resize()
          break
        case 'myResourceMemChart':
          this.myResourceMemChart = insChart
          insChart = drawLine(this.myResourceMemChart, xData, yData1)
          this.myResourceMemChart.resize()
          break
      }
    },
    toViewALarm() {
      this.$router.push({ path: '/alarm/index' })
    },
    resize() {
      if (this.myUserChart) this.myUserChart.resize()
      if (this.myTaskTimeChart) this.myTaskTimeChart.resize()
      if (this.myNewTaskChart) this.myNewTaskChart.resize()
      if (this.myTaskStatusChart) this.myTaskStatusChart.resize()
      if (this.myResourceChart) this.myResourceChart.resize()
    },
    handleTableHeaderclass() {
      return 'table-head-th'
    },
    // 查询概览
    _getDashboardOverview() {
      this.listLoading = true
      getDashboardOverview().then(res => {
        if (res.message.code === 0) {
          this.listLoading = false
          this.totalAlerts = res.data.total_alerts
          this.totalDatasets = res.data.total_datasets
          this.totalGpus = res.data.total_gpus
          this.totalJobs = res.data.total_jobs
          this.totalNodes = res.data.total_nodes
          this.totalPublicProjects = res.data.total_public_projects
          this.totalUsers = res.data.total_users
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 查询活跃用户数
    _getDashboardUsersView(period) {
      this.listLoading = true
      const query = `?query_interval=${Number(period)}`
      getDashboardUsersView(query).then(res => {
        this.listLoading = false
        if (res.message.code === 0) {
          const dateList = res.data.map(item => {
            const xItem = new Date(item[0]).Format('yyyy-MM-dd')
            return xItem
          })
          const valueList = res.data.map(item => {
            return item[1]
          })
          this.drawChart('myUserChart', dateList, valueList)
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 任务数量排行TOP10的用户
    _getDashboardTopUsers() {
      this.listLoading = true
      getDashboardTopUsers().then(res => {
        this.listLoading = false
        if (res.message.code === 0) {
          this.topUsers = res.data
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 查询活跃用户数
    _getDashboardTopUsersHours(period) {
      this.listLoading = true
      const query = `?query_interval=${Number(period)}`
      getDashboardTopUsersHours(query).then(res => {
        this.listLoading = false
        if (res.message.code === 0) {
          const userNameList = res.data.map(item => {
            return item.username
          })
          const valueList = res.data.map(item => {
            return item.value.toFixed(2)
          })
          this.drawChart('myTaskTimeChart', valueList, userNameList)
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 新建任务数
    _getDashboardJobsView(period) {
      this.listLoading = true
      const query = `?query_interval=${Number(period)}`
      getDashboardJobsView(query).then(res => {
        this.listLoading = false
        if (res.message.code === 0) {
          const dateList = res.data.map(item => {
            const xItem = new Date(item[0]).Format('yyyy-MM-dd')
            return xItem
          })
          const valueList = res.data.map(item => {
            return item[1]
          })
          this.drawChart('myNewTaskChart', dateList, valueList)
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 耗时任务排行
    _getDashboardTopJobsHoursView(period) {
      this.listLoading = true
      const query = `?query_interval=${Number(period)}`
      getDashboardTopJobsHoursView(query).then(res => {
        this.listLoading = false
        if (res.message.code === 0) {
          this.taskTimeList = res.data
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 任务统计分析 （成功失败）
    _getDashboardJobsStatusView(period) {
      this.listLoading = true
      const query = `?query_interval=${Number(period)}`
      getDashboardJobsStatusView(query).then(res => {
        this.listLoading = false
        if (res.message.code === 0) {
          const dateList = res.data.map(item => {
            const xItem = new Date(item[0]).Format('yyyy-MM-dd')
            return xItem
          })
          const successDataList = res.data.map(item => {
            return item[1]
          })
          const failureDataList = res.data.map(item => {
            return item[2]
          })
          this.drawChart('myTaskStatusChart', dateList, successDataList, failureDataList)
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 资源监控查询（GPU利用率、GPU分配率）
    _getDashboardResourceGPU(period) {
      this.listLoading = true
      const query = `?query_interval=${Number(period)}`
      getDashboardResourceGpuUtilView(query).then(res1 => {
        if (res1.message.code === 0) {
          const dateList = res1.data.map(item => {
            const xItem = new Date(item[0]).Format('yyyy-MM-dd')
            return xItem
          })
          const gpuUtilDataList = res1.data.map(item => {
            return item[1]
          })
          getDashboardResourceGpuAllocateView(query).then(res2 => {
            this.listLoading = false
            if (res2.message.code === 0) {
              const gpuAlloDataList = res2.data.map(item => {
                return item[1]
              })
              this.drawChart('myResourceGPUChart', dateList, gpuUtilDataList, gpuAlloDataList)
            } else {
              this.$message({ message: res2.message.message, showClose: true, type: 'error' })
            }
          })
        } else {
          this.$message({ message: res1.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 资源监控查询（CPU分配率）
    _getDashboardResourceCPU(period) {
      this.listLoading = true
      const query = `?query_interval=${Number(period)}`
      getDashboardResourceCpuView(query).then(res => {
        this.listLoading = false
        if (res.message.code === 0) {
          const dateList = res.data.map(item => {
            const xItem = new Date(item[0]).Format('yyyy-MM-dd')
            return xItem
          })
          const cpuUtilDataList = res.data.map(item => {
            return item[1]
          })
          this.drawChart('myResourceCPUChart', dateList, cpuUtilDataList)
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    // 资源监控查询（内存分配率）
    _getDashboardResourceMem(period) {
      this.listLoading = true
      const query = `?query_interval=${Number(period)}`
      getDashboardResourceMemoryView(query).then(res => {
        this.listLoading = false
        if (res.message.code === 0) {
          const dateList = res.data.map(item => {
            const xItem = new Date(item[0]).Format('yyyy-MM-dd')
            return xItem
          })
          const memUtilDataList = res.data.map(item => {
            return item[1]
          })
          this.drawChart('myResourceMemChart', dateList, memUtilDataList)
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.dashboard {
  &-container {
    padding: 20px;
    .dashboard-overview {
      background: #ffffff;
    }
    .overview-tags {
      display: flex;
      justify-content: space-around;
      padding: 30px 0px;
      margin: 0;
      .overview-tags-item {
        list-style-type: none;
        font-size: 14px;
        color: #000000;
        font-weight: 600;
        line-height: 18px;
        .overview-tags-item-title {
          color: #000;
          opacity: .45;
          margin-bottom: 10px;
        }
        .overview-tags-item-content {
          display: flex;
          justify-content: center;
          align-items: baseline;
          .item-content-num {
            font-size: 18px;
          }
          .item-content-unit {
            opacity: .45;
            font-size: 12px;
            margin-left: 5px;
          }
          .view-alarm {
            color: #f56c6c;
            margin-left: 5px;
            cursor: pointer;
          }
        }
      }
    }
  }
  &-body {
    background: #ffffff;
    .dashboard-body-tabs {
      padding: 20px 40px;
      .dashboard-body-tabs-item {
        list-style-type: none;
        display: inline-block;
        color: #000;
        opacity: .45;
        font-size: 16px;
        font-weight: 600;
        margin-right: 20px;
        padding-bottom: 5px;
        cursor: pointer;
      }
      .dashboard-body-tabs-active-tab {
        opacity: .7!important;
        border-bottom: 2px solid #000;
      }
    }
    .dashboard-body-content {
      .chart-header {
        display: flex;
        justify-content: space-between;
        padding: 0 40px;
        font-size: 14px;
        font-weight: 600;
        opacity: .7;
        align-items: center;
      }
      .users-info {
        display: flex;
        justify-content: space-between;
        padding: 20px 40px;
        font-size: 14px;
        font-weight: 600;
        opacity: .7;
        border-top: 3px solid #f4f4f5;
        .users-info-header {
          display: flex;
          align-items: center;
          justify-content: space-between;
          line-height: 28px;
        }
        .users-info-left {
          width: 40%;
          background: #f4f4f5;
          padding: 10px 20px;
          .users-info-top-user-list {
            padding: 0;
            .users-info-top-user-item {
              list-style-type: none;
              width: 50%;
              display: inline-block;
              .top-user-item-value {
                font-size: 12px;
                font-weight: normal;
                color: #000000;
                opacity: .7;
              }
            }
          }
        }
        .users-info-right {
          width: 60%;
          margin-left: 20px;
          background: #f4f4f5;
          padding: 10px 20px;
        }
      }
      .task-analysis-header {
        padding: 0 40px;
        font-size: 14px;
        color: #000000;
        opacity: .7;
        display: inline-flex;
        margin-bottom: 20px;
        .task-analysis-item {
          border: 1px solid #ccc;
          display: inline-block;
          padding: 8px 12px;
          cursor: pointer;
        }
        .task-analysis-header-active-tab {
          border: none!important;
          background: #2e94f9;
          color: #fff;
        }
      }
      .task-time-box {
        border-top: 3px solid #f4f4f5;
        .task-time-table-header {
          padding: 40px;
          font-size: 14px;
          color: #000000;
          opacity: .7;
          font-weight: 600;
          display: flex;
          justify-content: space-between;
          align-items: center;
        }
        .task-time-table {
          padding: 0 40px 80px;
        }
      }
    }
  }
  .table-head-th {
    background: #2e94f9;
  }
}
</style>
